package cn.Alibaba.basic.service.impl;

import cn.Alibaba.basic.constant.VerifyConstants;
import cn.Alibaba.basic.dto.SmsCodeDto;
import cn.Alibaba.basic.exception.BusinessException;
import cn.Alibaba.basic.service.IVerifyService;
import cn.Alibaba.basic.util.SmsUtils;
import cn.Alibaba.basic.util.StrUtils;
import cn.Alibaba.basic.util.VerifyCodeUtils;
import cn.Alibaba.user.domain.User;
import cn.Alibaba.user.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.concurrent.TimeUnit;

@Service
public class VerifyServiceImpl implements IVerifyService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserMapper userMapper;

    @Override
    public String getImgCode(String key) {

        //判断key是否为空
        if (StringUtils.isEmpty(key)){
            throw new BusinessException("key为空");
        }

        //获取随机验证码
        String code = StrUtils.getComplexRandomString(4);
        //将验证码存放到redis，设置5分钟过期
        redisTemplate.opsForValue().set(key,code,5, TimeUnit.MINUTES);

        //把验证码的值合并到图片，使用Base64编码。并返回base64编码的字符串
        return VerifyCodeUtils.verifyCode(110, 40, code);


    }

    @Override
    public void sendSmsCode(SmsCodeDto smsCodeDto) {

        String imageCode = smsCodeDto.getImageCode();

        String imageCodeKey = smsCodeDto.getImageCodeKey();

        String phone = smsCodeDto.getPhone();

        if (StringUtils.isEmpty(imageCode)
                ||StringUtils.isEmpty(imageCodeKey)|| StringUtils.isEmpty(phone))
       {
            throw  new  BusinessException("参数不能为空！");

        }

        // 1.图片验证码是否过期
        Object imageCodeValue = redisTemplate.opsForValue().get(imageCodeKey);
        if (imageCodeValue==null){
            throw  new  BusinessException("图片验证码过期，请重新输入");
        }

        // 2.图片验证码是否正确
        if (!imageCodeValue.toString().equalsIgnoreCase(imageCode)){

            throw  new  BusinessException("图片验证码不正确，请重新输入");
        }

        // 3.校验 - 手机号是否被注册
        User user = userMapper.loadByPhone(phone);

        if (user!=null){

            throw new BusinessException("该手机已经注册，请直接登录!");
        }

        // 4. 判断是否是第一次发送请求，或者是验证码过期  从redis中取
        Object value  = redisTemplate.opsForValue().get(phone + VerifyConstants.PHONEREGISTER);

        String code = null;
        // 4.1. 如果取不到，没有发送过，获取过期了， 直接生成一个新的验证码保存到redis
        if (value==null){
            code= StrUtils.getComplexRandomString(6);
        }else {
            // 4.2. 如果取到了。判断是否超过一分钟。
            String redisTime  = value.toString().split(":")[1];
            Long Ltime = Long.valueOf(redisTime);

            // 4.2.1： 如果没超过1分钟，直接提示用户，1分钟之内不能多次发送
            if (System.currentTimeMillis()-Ltime< 1*60*1000){
                throw new BusinessException("一分钟只能不能发送多次！");
            }else {
                // 4.2.2： 如果超过了一分钟，刷新过期时间，
                code=value.toString().split(":")[0];
            }
        }

        // 4.2.2： 把code存入redisz中
        redisTemplate.opsForValue().set(phone+VerifyConstants.PHONEREGISTER,
                code+":"+System.currentTimeMillis(),3,TimeUnit.MINUTES);


        //SmsUtils.sendSms(phone,"您的验证码为："+code+",请在三分钟之内使用");
        System.out.println("您的验证码为："+code+",请在三分钟之内使用");
    }

    @Override
    public void binderSmsCode(SmsCodeDto smsCodeDto) {


        String phone = smsCodeDto.getPhone();

        if (StringUtils.isEmpty(phone))
        {
            throw  new  BusinessException("手机号不能为空！");

        }

        // 4. 判断是否是第一次发送请求，或者是验证码过期  从redis中取
        Object value  = redisTemplate.opsForValue().get(phone + VerifyConstants.BINDER_PREFIX);

        String code = null;
        // 4.1. 如果取不到，没有发送过，获取过期了， 直接生成一个新的验证码保存到redis
        if (value==null){
            code= StrUtils.getComplexRandomString(6);
        }else {
            // 4.2. 如果取到了。判断是否超过一分钟。
            String redisTime  = value.toString().split(":")[1];
            Long Ltime = Long.valueOf(redisTime);

            // 4.2.1： 如果没超过1分钟，直接提示用户，1分钟之内不能多次发送
            if (System.currentTimeMillis()-Ltime< 1*60*1000){
                throw new BusinessException("一分钟只能不能发送多次！");
            }else {
                // 4.2.2： 如果超过了一分钟，刷新过期时间，
                code=value.toString().split(":")[0];
            }
        }

        // 4.2.2： 把code存入redisz中
        redisTemplate.opsForValue().set(phone+VerifyConstants.BINDER_PREFIX,
                code+":"+System.currentTimeMillis(),3,TimeUnit.MINUTES);


        //SmsUtils.sendSms(phone,"您的验证码为："+code+",请在三分钟之内使用");
        System.out.println("您的验证码为："+code+",请在三分钟之内使用");

    }


}
